package org.suburban.servlet.staticdata;
import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.logging.Logger;
import org.suburban.data.DirectionRepository;
import org.suburban.resource.Queues;
import org.suburban.resource.RequestParams;
import org.suburban.resource.URLs;

import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
/**
 * class to "parse" 'directions' static data 
 * @author Alexey Palamarchuk (slonnik@gmail.com)
 *
 */
public class DirectionsCracker extends DefaultHandler{
	/** flag to indicate we start parsing direction list*/
	private boolean parsingList = false;
	/** flag to indicate we start parsing outer 'li' tag*/
	private boolean parsingItemOuter = false;
	/** flag to indicate we start parsing item itself*/
	private boolean parsingItem = false;
	/** item to store data*/
	private final DirectionItem item = new DirectionItem();
	/** logger*/
	private static final Logger logger = Logger.getLogger(DirectionsCracker.class.getName());
	/** class to store direction data*/
	class DirectionItem
	{
		/** direction id*/
		String id;
		/** direction human readable name*/
		String name;
		
		/** reset item state*/
		void clear()
		{
			id = name = null;
		}
		
		@Override
		public String toString()
		{
			return String.format("id=%1$s; name=%2$s", id, name);
		}
	}
	
	@Override
	public void startElement(String arg0, String arg1, String arg2,
			Attributes arg3) throws SAXException {
		/** arg3  == qName*/
		if(arg2.equalsIgnoreCase("ul"))
		{
			parsingList = true;
			return;
		}
		if(!parsingList)
		{
			/** we parse other items only for list of directions*/
			return;
		}
		if(arg2.equalsIgnoreCase("li"))
		{
			parsingItemOuter = true;
			item.clear();
			return;
		}
		if(!parsingItemOuter)
		{
			/** we parse other items only in case of parsingItemOuter == true*/
			return;
		}
		
		if(arg2.equalsIgnoreCase("a"))
		{
			parsingItem = true;
			String value = arg3.getValue("href");
			item.id = value.split("=")[1].trim();
		}
	}
	
	@Override
	public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
	
		if(parsingItem)
		{
			item.name = new String(arg0, arg1, arg2);
		}
	}
	
	@Override
	public void endElement(String arg0, String arg1, String arg2)
			throws SAXException {
	
		/** arg3  == qName*/
		if(arg2.equalsIgnoreCase("ul"))
		{
			parsingList = false;
			return;
		}
		if(arg2.equalsIgnoreCase("li"))
		{
			parsingItemOuter = false;
			/** trace direction info*/
			logger.fine(item.toString());
			
			if(item.id.contains("_unknown"))
			{
				/**we look only for 'well-known' directions */
				return;
			}
			/** save data into database*/
			DirectionRepository.put(item.id, item.name);
			Queue queue = QueueFactory.getQueue(Queues.STATIC_DATA);
			/** query for stations*/
			queue.add(withUrl(URLs.STATIONS).param(RequestParams.DIRECTION, item.id));
			return;
		}
		if(arg2.equalsIgnoreCase("a"))
		{
			parsingItem = false;
		}
	}
}
